package eclipse.controller.util;
import java.awt.Color;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
/**
* Implements a log4j appender which writes to a swing JTextPane
*
* This code was copied from
*
* "jakarta-log4j-1.2.15\apache-log4j-1.2.15\contribs\SvenReimers\gui\TextPaneAppender.java
* " (which did not work properly, not even compile) and adapted for my needs.
*
* added a 'maxLines' constructor parameter that defines the maximum numbers of lines allowed
* truncating what's old (FIFO)
*
* @author bender
*/
public class JTextPaneAppender extends AppenderSkeleton {
/** */
JTextPane myTextPane;
int maxLines;
/** */
Hashtable<String, MutableAttributeSet> myAttributeSet;
/**
* Constructor
*
* @param aLayout
* @param aName
* @param aFilterArray
* @param aTextPane
* @param maxLines
*/
public JTextPaneAppender(Layout aLayout, String aName,
Filter[] aFilterArray, JTextPane aTextPane, int maxLines) {
this();
this.layout = aLayout;
this.name = aName;
this.maxLines = maxLines;
myTextPane = aTextPane;
if (aFilterArray != null) {
for (int i = 0; i < aFilterArray.length; i++) {
if (aFilterArray[i] != null) {
addFilter(aFilterArray[i]);
} // if aFilterArray[i] != null]
} // for i
} // if aFilterArray != null
createAttributes();
}
/**
* Constructor
*
*/
public JTextPaneAppender() {
super();
createAttributes();
}
/**
* @see org.apache.log4j.AppenderSkeleton#close()
*/
@Override
public void close() {
//
}
private void createAttributes() {
String prio[] = new String[6];
prio[0] = Level.FATAL.toString();
prio[1] = Level.ERROR.toString();
prio[2] = Level.WARN.toString();
prio[3] = Level.INFO.toString();
prio[4] = Level.DEBUG.toString();
prio[5] = Level.TRACE.toString();
myAttributeSet = new Hashtable<String, MutableAttributeSet>();
for (int i = 0; i < prio.length; i++) {
MutableAttributeSet att = new SimpleAttributeSet();
myAttributeSet.put(prio[i], att);
StyleConstants.setFontSize(att, 14);
}
StyleConstants.setForeground(
myAttributeSet.get(Level.FATAL.toString()), Color.red);
StyleConstants.setForeground(
myAttributeSet.get(Level.ERROR.toString()), Color.red);
StyleConstants.setForeground(myAttributeSet.get(Level.WARN.toString()),
Color.orange);
StyleConstants.setForeground(myAttributeSet.get(Level.INFO.toString()),
Color.black);
StyleConstants.setForeground(
myAttributeSet.get(Level.DEBUG.toString()), Color.black);
StyleConstants.setForeground(
myAttributeSet.get(Level.TRACE.toString()), Color.black);
}
/**
* @see org.apache.log4j.AppenderSkeleton#append(org.apache.log4j.spi.LoggingEvent)
*/
@Override
public void append(LoggingEvent event) {
if (myTextPane == null) {
LogLog.warn("TextPane is not initialized");
return;
} // if myTextPane == null
String text = this.layout.format(event);
String[] stackTrace = event.getThrowableStrRep();
if (stackTrace != null) {
StringBuffer sb = new StringBuffer(text);
for (int i = 0; i < stackTrace.length; i++) {
sb.append(" ").append(stackTrace[i]).append("\n");
} // for i
text = sb.toString();
}
StyledDocument myDoc = myTextPane.getStyledDocument();
try {
myDoc.insertString(myDoc.getLength(), text, myAttributeSet
.get(event.getLevel().toString()));
// Removes the same qty of the text added if line count > maxLines
if (myDoc.getDefaultRootElement().getElementCount() > maxLines)
myDoc.remove(0, text.length());
} catch (BadLocationException badex) {
System.err.println(badex);
}
myTextPane.setCaretPosition(myDoc.getLength());
}
/**
* getTextPane
* <p>
*
* @return
*/
public JTextPane getTextPane() {
return myTextPane;
}
/**
* setTextPane
* <p>
*
* @param aTextpane
*/
public void setTextPane(JTextPane aTextpane) {
myTextPane = aTextpane;
}
private void setColor(Level p, Color v) {
StyleConstants.setForeground(myAttributeSet.get(p), v);
}
private Color getColor(Level p) {
Color c = StyleConstants.getForeground(myAttributeSet.get(p));
return c == null ? null : c;
}
// ///////////////////////////////////////////////////////////////////
// option setters and getters
/**
* setColorEmerg
* <p>
*
* @param color
*/
public void setColorEmerg(Color color) {
setColor(Level.FATAL, color);
}
/**
* getColorEmerg
* <p>
*
* @return
*/
public Color getColorEmerg() {
return getColor(Level.FATAL);
}
/**
* setColorError
* <p>
*
* @param color
*/
public void setColorError(Color color) {
setColor(Level.ERROR, color);
}
/**
* getColorError
* <p>
*
* @return
*/
public Color getColorError() {
return getColor(Level.ERROR);
}
/**
* setColorWarn
* <p>
*
* @param color
*/
public void setColorWarn(Color color) {
setColor(Level.WARN, color);
}
/**
* getColorWarn
* <p>
*
* @return
*/
public Color getColorWarn() {
return getColor(Level.WARN);
}
/**
* setColorInfo
* <p>
*
* @param color
*/
public void setColorInfo(Color color) {
setColor(Level.INFO, color);
}
/**
* getColorInfo
* <p>
*
* @return
*/
public Color getColorInfo() {
return getColor(Level.INFO);
}
/**
* setColorDebug
* <p>
*
* @param color
*/
public void setColorDebug(Color color) {
setColor(Level.DEBUG, color);
}
/**
* getColorDebug
* <p>
*
* @return
*/
public Color getColorDebug() {
return getColor(Level.DEBUG);
}
/**
* Sets the font size of all Level's
* <p>
*
* @param aSize
*/
public void setFontSize(int aSize) {
Enumeration<MutableAttributeSet> e = myAttributeSet.elements();
while (e.hasMoreElements()) {
StyleConstants.setFontSize(e.nextElement(), aSize);
}
return;
}
/**
* Sets the font size of a particular Level
* <p>
*
* @param aSize
* @param aLevel
*/
public void setFontSize(int aSize, Level aLevel) {
MutableAttributeSet set = myAttributeSet.get(aLevel);
if (set != null) {
StyleConstants.setFontSize(set, aSize);
} // if set != null
}
/**
* getFontSize
* <p>
*
* @param aLevel
* @return
*/
public int getFontSize(Level aLevel) {
AttributeSet attrSet = myAttributeSet.get(aLevel);
if (attrSet == null) {
throw new IllegalArgumentException("Unhandled Level: "
+ aLevel.toString());
} // if attrSet == null
return StyleConstants.getFontSize(attrSet);
}
/**
* Sets the font name of all known Level's
* <p>
*
* @param aName
*/
public void setFontName(String aName) {
Enumeration<MutableAttributeSet> e = myAttributeSet.elements();
while (e.hasMoreElements()) {
StyleConstants.setFontFamily(e.nextElement(), aName);
}
return;
}
/**
* setFontName
* <p>
*
* @param aName
* @param aLevel
*/
public void setFontName(String aName, Level aLevel) {
MutableAttributeSet set = myAttributeSet.get(aLevel);
if (set != null) {
StyleConstants.setFontFamily(set, aName);
}
return;
}
/**
* Retrieves the font name of a particular Level
* <p>
*
* @param aLevel
* @return
*/
public String getFontName(Level aLevel) {
AttributeSet attrSet = myAttributeSet.get(aLevel);
if (attrSet == null) {
throw new IllegalArgumentException("Unhandled Level: "
+ aLevel.toString());
} // if attrSet == null
return StyleConstants.getFontFamily(attrSet);
}
/**
* @see org.apache.log4j.AppenderSkeleton#requiresLayout()
*/
@Override
public boolean requiresLayout() {
return true;
}
}